package utils

import (
	"bytes"
	"compress/gzip"
	"database/sql"
	"fmt"
	"gin-epg/internal/app/entity"
	"gin-epg/internal/app/model"
	"github.com/jinzhu/gorm"
	"io/ioutil"
	"net/http"
	"time"
)

// 定义 HTTP 请求方法
func FetchXML(url string) ([]byte, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to fetch XML: status code %d", resp.StatusCode)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	// 检查是否为 gzip 压缩文件
	if isGzip(body) {
		return decompressGzip(body)
	}

	return body, nil
}

// 检查是否为 gzip 压缩文件
func isGzip(data []byte) bool {
	return len(data) >= 2 && data[0] == 0x1f && data[1] == 0x8b
}

// 解压 gzip 压缩文件
func decompressGzip(data []byte) ([]byte, error) {
	reader, err := gzip.NewReader(bytes.NewReader(data))
	if err != nil {
		return nil, err
	}
	defer reader.Close()

	return ioutil.ReadAll(reader)
}

// 定义数据库操作方法
func FindOne(db *gorm.DB, channel, date, start, source string) (*entity.EpgProgramCollect, error) {
	var epc entity.EpgProgramCollect
	if err := db.Where("channel = ? AND date = ? AND start = ? AND source = ?", channel, date, start, source).First(&epc).Error; err != nil {
		if gorm.IsRecordNotFoundError(err) {
			return nil, nil
		}
		return nil, err
	}
	return &epc, nil
}

func Update(db *gorm.DB, channel, date, start, source, end, title string) error {
	return db.Model(&entity.EpgProgramCollect{}).Where("channel = ? AND date = ? AND start = ? AND source = ?", channel, date, start, source).Update(map[string]interface{}{
		"end":         end,
		"title":       title,
		"update_time": entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}},
	}).Error
}

func Insert(db *gorm.DB, epc *entity.EpgProgramCollect) error {
	return db.Create(epc).Error
}

// 构造频道id--频道名的map
func BuildChannelMap(tv *model.TV) map[string]string {
	channelMap := make(map[string]string)
	for _, channel := range tv.Channels {
		channelMap[channel.ID] = channel.DisplayName
	}
	return channelMap
}

// 定义日期格式化方法
func FormatToDate(dateStr string) time.Time {
	layout := "20060102150400 -0700"
	t, _ := time.Parse(layout, dateStr)
	return t
}
